<script setup lang="ts">
import { getTaskInfoApi, startTaskApi } from "@/api/task"
import { TaskBaseInfo } from "@/api/task/types/task"
import { TabTypeEnum, TASK_EVAL_INDEX, TASK_MODE, taskStatusOptions } from "@/constants/other-keys"
import { ElMessage } from "element-plus"
import { cloneDeep } from "lodash-es"
import { computed, nextTick, onBeforeUnmount, onMounted, ref, watch } from "vue"
import TrainChart from "@/views/task/static-task/component/train-chart.vue"
import EvalChart from "@/views/task/static-task/component/eval-chart.vue"
import TaskFile from "@/views/task/game-task/component/task-file.vue"

interface Props {
  id: string | undefined | null
  trainEndFlag: boolean
  type: TASK_MODE
}
const props = defineProps<Props>()
const emit = defineEmits(["update:trainEndFlag"])
let timer: number | null = null
const taskId = ref<string | undefined>(props.id as string)
type TabValueType = "status" | "file"
const tabValue = ref<TabValueType>("status")
const TrainChartRef = ref()
const EvalChartRef = ref()
const percentage = ref<number>(0)
const round = ref<number>(0)
const DEFAULT_FORM_DATA: TaskBaseInfo = {
  task_id: undefined,
  task_name: "",
  task_process: 0,
  task_type: TabTypeEnum.STATIC,
  task_status: 0,
  task_eval_tag: []
}
const formData = ref<TaskBaseInfo>(cloneDeep(DEFAULT_FORM_DATA))

const taskStatusMap = computed<{ [propName: string]: string }>(() => {
  return taskStatusOptions.value.reduce((acc: { [propName: string]: string }, curr) => {
    acc[curr.value] = curr.name
    return acc
  }, {})
})

const getTaskInfo = () => {
  taskId.value &&
    getTaskInfoApi(taskId.value).then(({ data }) => {
      formData.value = {
        task_id: data.task_id,
        task_name: data.task_name,
        task_process: data.task_process,
        task_type: TabTypeEnum.STATIC,
        task_status: data.task_status,
        task_eval_tag: data.task_eval_tag && JSON.parse(data.task_eval_tag)
      }
      round.value = Number(JSON.parse(data.task_param).episode_config.max_episode)
      percentage.value = data.task_process as number
      if (data.task_status == 2) {
        percentage.value > 0 ? 100 : percentage.value
      }
      if (data.task_status == 3) {
        ElMessage.error("任务运行错误")
      }
      if (data.task_status == 4) {
        ElMessage.error("任务暂停")
      }
    })
}

const startLoading = ref(false)
const startTask = () => {
  startLoading.value = true
  taskId.value &&
    startTaskApi(taskId.value)
      .then(() => {
        ElMessage.success("任务已开始！")
        startLoading.value = false
        formData.value.task_status = 1
        formData.value.task_process = 0
      })
      .finally(() => {
        startLoading.value = false
      })
}

const resize = () => {
  nextTick(() => {
    if (props.type == "Train") TrainChartRef.value && TrainChartRef.value.resize()
    if (props.type == "Inference") EvalChartRef.value && EvalChartRef.value.resize()
  })
}

const refresh = () => {
  getTaskInfo()
}

const getTrainProcess = () => {
  return percentage.value
}

watch(
  () => tabValue.value,
  () => {
    if (tabValue.value == "status") resize()
  }
)

watch(
  () => props.id,
  () => {
    taskId.value = props.id as string
  }
)

const statusText = computed(() => {
  if (formData.value.task_status == undefined) {
    return ""
  }
  return taskStatusMap.value[formData.value.task_status]
})
// 预期训练时长
const trainDuration = computed(() => {
  return round.value * 30
})

watch(
  () => percentage.value,
  () => {
    emit("update:trainEndFlag", percentage.value == 100 ? true : false)
  }
)

onMounted(() => {
  refresh()
  timer = Number(setInterval(refresh, 1000 * 60))
})
onBeforeUnmount(() => {
  timer && clearInterval(timer)
})

defineExpose({ resize, getTrainProcess })
</script>

<template>
  <div class="taskedit-form">
    <div class="header mb-5 mt-10">
      <el-text class="w-300px" truncated>任务名称：{{ formData.task_name }}</el-text>
      <el-text class="w-200px" truncated> 任务状态：{{ statusText }} </el-text>
      <el-text> 预期训练时长：{{ trainDuration }} 秒 </el-text>
    </div>
    <el-card class="mb-6" body-class="control-toolbar">
      <el-tooltip class="box-item" effect="dark" content="开始">
        <el-button
          class="item"
          text
          size="large"
          :loading="startLoading"
          :disabled="formData.task_status == 1"
          @click="startTask"
        >
          <el-space>
            <SvgIcon name="video-start" class="success" />
          </el-space>
        </el-button>
      </el-tooltip>
      <div class="process">
        <div class="describe">进度：{{ formData.task_process }}%</div>
        <div class="progress">
          <el-progress
            :percentage="percentage == 0 && formData.task_status == 1 ? 100 : percentage"
            :stroke-width="18"
            :show-text="false"
            :status="percentage == 100 ? '' : 'warning'"
            :striped="percentage != 100"
            :striped-flow="percentage != 100"
            :duration="percentage == 100 ? 0 : 20"
            :color="percentage == 0 && formData.task_status == 1 ? 'rgba(64, 158, 255, 0.1)' : ''"
          />
        </div>
      </div>
    </el-card>
    <el-card never>
      <el-tabs v-model="tabValue" type="card" class="demo-tabs">
        <el-tab-pane label="任务曲线" name="status">
          <TrainChart
            v-if="props.type == 'Train' && tabValue == 'status'"
            ref="TrainChartRef"
            :id="taskId"
            :task-status="formData.task_status"
          />
          <EvalChart
            v-if="props.type == 'Inference' && tabValue == 'status'"
            ref="EvalChartRef"
            :id="taskId"
            :task-status="formData.task_status"
            :task-process="formData.task_process"
            :eval-index="formData.task_eval_tag as TASK_EVAL_INDEX[]"
          />
        </el-tab-pane>
        <el-tab-pane v-if="props.type == 'Train'" label="任务文件" name="file">
          <TaskFile v-if="tabValue == 'file'" :id="taskId" />
        </el-tab-pane>
      </el-tabs>
    </el-card>
  </div>
</template>
<style lang="scss" scoped>
.el-progress {
  width: 100%;
}

.taskedit-form {
  margin: 0 auto;
  margin-top: 0;
}

@media screen and (max-width: 640px) {
  .taskedit-form {
    width: 100%;
  }
}
@media screen and (min-width: 660px) {
  .taskedit-form {
    width: 100%;
  }
}
@media screen and (min-width: 1200px) {
  .taskedit-form {
    width: 80%;
  }
}

:deep(.control-toolbar) {
  display: flex;
  flex-direction: row;
  align-items: center;
  .el-button.is-disabled {
    .svg-icon {
      &.success {
        fill: rgba(148.6, 212.3, 117.1, 0.3);
      }
      &.primary {
        fill: rgb(121.3, 187.1, 255, 0.3);
      }
      &.danger {
        fill: rgb(248, 152.1, 152.1, 0.3);
      }
    }
  }
  .process {
    flex: 1;
    display: flex;
    align-items: center;
    padding: 0 10px;
    .describe {
      padding-right: 10px;
      font-size: 18px;
    }
    .progress {
      flex: 1;
    }
  }
  .item {
    height: 60px;
    padding: 10px;
  }
  .svg-icon {
    width: 2.5em;
    height: 2.5em;
    &.success {
      fill: rgb(148.6, 212.3, 117.1);
    }
    &.primary {
      fill: rgb(121.3, 187.1, 255);
    }
    &.danger {
      fill: rgb(248, 152.1, 152.1);
    }
  }
}
.el-button + .el-button {
  margin-left: 0;
}
.el-text + .el-text {
  margin-left: 20px;
}
</style>
